library(MSnbase)
Loading required package: BiocGenerics
Loading required package: parallel

Attaching package: ‘BiocGenerics’

The following objects are masked from ‘package:parallel’:

    clusterApply, clusterApplyLB, clusterCall, clusterEvalQ, clusterExport, clusterMap, parApply,
    parCapply, parLapply, parLapplyLB, parRapply, parSapply, parSapplyLB

The following objects are masked from ‘package:stats’:

    IQR, mad, sd, var, xtabs

The following objects are masked from ‘package:base’:

    anyDuplicated, append, as.data.frame, basename, cbind, colnames, dirname, do.call, duplicated,
    eval, evalq, Filter, Find, get, grep, grepl, intersect, is.unsorted, lapply, Map, mapply, match,
    mget, order, paste, pmax, pmax.int, pmin, pmin.int, Position, rank, rbind, Reduce, rownames,
    sapply, setdiff, sort, table, tapply, union, unique, unsplit, which, which.max, which.min

Loading required package: Biobase
Welcome to Bioconductor

    Vignettes contain introductory material; view with 'browseVignettes()'. To cite Bioconductor,
    see 'citation("Biobase")', and for packages 'citation("pkgname")'.

Loading required package: mzR
Loading required package: Rcpp
Loading required package: S4Vectors
Loading required package: stats4

Attaching package: ‘S4Vectors’

The following object is masked from ‘package:base’:

    expand.grid

Loading required package: ProtGenerics

Attaching package: ‘ProtGenerics’

The following object is masked from ‘package:stats’:

    smooth


This is MSnbase version 2.14.2 
  Visit https://lgatto.github.io/MSnbase/ to get started.


Attaching package: ‘MSnbase’

The following object is masked from ‘package:base’:

    trimws
library(pRoloc)
Loading required package: MLInterfaces
Loading required package: annotate
Loading required package: AnnotationDbi
Loading required package: IRanges
Loading required package: XML

Attaching package: ‘annotate’

The following object is masked from ‘package:mzR’:

    nChrom

Loading required package: cluster
Loading required package: BiocParallel
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     

This is pRoloc version 1.28.0 
  Visit https://lgatto.github.io/pRoloc/ to get started.
library(pRolocExt)
library(tidyverse)
── Attaching packages ──────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.2     ✓ purrr   0.3.4
✓ tibble  3.0.3     ✓ dplyr   1.0.4
✓ tidyr   1.1.2     ✓ stringr 1.4.0
✓ readr   1.3.1     ✓ forcats 0.5.0
── Conflicts ─────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::collapse()   masks IRanges::collapse()
x dplyr::combine()    masks MSnbase::combine(), Biobase::combine(), BiocGenerics::combine()
x dplyr::desc()       masks IRanges::desc()
x tidyr::expand()     masks S4Vectors::expand()
x dplyr::filter()     masks stats::filter()
x dplyr::first()      masks S4Vectors::first()
x dplyr::lag()        masks stats::lag()
x ggplot2::Position() masks BiocGenerics::Position(), base::Position()
x purrr::reduce()     masks IRanges::reduce(), MSnbase::reduce()
x dplyr::rename()     masks S4Vectors::rename()
x dplyr::select()     masks AnnotationDbi::select()
x dplyr::slice()      masks IRanges::slice()
library(camprotR)
library(biobroom)
Loading required package: broom
Registered S3 methods overwritten by 'biobroom':
  method      from 
  glance.list broom
  tidy.list   broom
source('../plot_foi.R')

colours <- readRDS('../../../../6_shiny_app/out/shiny_colours.rds')$Protein

Read in BANDLE results and fully annotated LOPIT data

diff_loc <- readRDS('../../out/bandle_diff_loc_all_unique.rds')

combined_protein_res_inc_bandle <- readRDS('../../out/combined_protein_res_inc_bandle_loc.rds')

Just looking at the profile for ZNF622

marker_profiles <- combined_protein_res_inc_bandle %>% names() %>%
  lapply(function(name){
    mrkConsProfiles(combined_protein_res_inc_bandle[[name]])[c('ER', 'RIBOSOME'),] %>%
      data.frame() %>%
      tibble::rownames_to_column('markers') %>%
      pivot_longer(cols=-markers, names_to='sample') %>%
      mutate(sample=remove_x(sample)) %>%
      mutate(condition=name) %>%
      merge(pData(combined_protein_res_inc_bandle[[name]])[,c('fraction', 'replicate')],
            by.x='sample', by.y='row.names')
  }) %>% bind_rows() %>%
  mutate(markers=update_loc_names(markers))
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
foi_profile <- combined_protein_res_inc_bandle %>%
  lapply(function(x) tidy(x['Q969S3',], addPheno=TRUE)) %>%
  bind_rows() %>%
  mutate(markers='ZNF622')
`tbl_df()` is deprecated as of dplyr 1.0.0.
Please use `tibble::as_tibble()` instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_warnings()` to see where this warning was generated.
p <- bind_rows(foi_profile, marker_profiles) %>%
  mutate(condition=recode(condition, 'Thapsigargin'='UPR')) %>%
  ggplot(aes(fraction, value, group=interaction(replicate, markers), colour=markers)) +
  geom_line(size=1) +
  facet_grid(condition~(paste0('Replicate ', replicate))) +
  scale_x_continuous(breaks=1:8, name='Fraction') +
  theme_camprot(base_size=15, base_family='sans', border=FALSE) +
  scale_colour_manual(values=c(colours[c('ER', 'RIBOSOME')], get_cat_palette(7)[7]), name='') +
  theme(strip.background=element_blank()) +
  xlab('Fraction') +
  ylab('Abundance (sum norm.)')

print(p)
ggsave('../../../../5_manuscript_figures/Figure_5/model/znf622.png', width=7, height=3.5)
ggsave('../../../../5_manuscript_figures/Figure_5/model/znf622.pdf', width=7, height=3.5)

NA
NA
NA
NA

ZNF622 and CAMK2D

foi_for_validation <- c('Q969S3', 'Q13557')
compare_profiles(foi_for_validation)


diff_loc %>% filter(protein %in% foi_for_validation)

Now, onto the proteins moving away from the ribosome.

bandle_from_ribosome <- diff_loc %>%
  filter(bandle.allocation.dmso.minimal=='RIBOSOME', level!='Candidate')

print(bandle_from_ribosome)

compare_profiles(bandle_from_ribosome$protein)


plot_fois(as.character(bandle_from_ribosome$protein), foi_name='Away from ribosome', feature_col='bandle_alloc',
          moi=c('Cytosol', 'Ribosome', 'ER', 'Nucleus', 'Protein Complex'), plot_tsne=TRUE, unknown_desc='Undefined')

NA
NA

PABPC1, PABPC4, UPF1 & STAU2 seem quite likely to be moving to a Stress Granule (SG) profile given a) They are associated with ribosomes when translation is active, b) most are known to be associated with SG upon stress & c) they increase in abundance in the fractions indicative of granules in the LoRNA data (fraction 5 & 6).

Whereas, MAGEB2 & PA2G4 seem to move towards cytosol if anything.

PA2G4 - regulates cap-independent IRES-mediated translation

Can we identify further proteins which are similarly localised in Tg by just using correlation with the above.

potential_sg_markers <- bandle_from_ribosome %>% filter(grepl('(PABP|UPF1|STAU2)', `GENES`)) %>% pull(protein)

p <- compare_profiles(potential_sg_markers)
print(p)

ggsave('../../../../5_manuscript_figures/Figure_4/granules/bandle_reloc.png', width=5, height=5)
ggsave('../../../../5_manuscript_figures/Figure_4/granules/bandle_reloc.pdf', width=5, height=5)


plot_fois(potential_sg_markers, foi_name='PABPC1/4, UPF1, STAU2', feature_col='bandle_alloc',
          moi=c('Cytosol', 'Nucleus', 'Ribosome'), plot_tsne=TRUE, unknown_desc='Undefined', )

NA

plot_tsne(combined_protein_res_inc_bandle$DMSO, 'markers')

plot_tsne(combined_protein_res_inc_bandle$Thapsigargin, 'markers')

plot_tsne(combined_protein_res_inc_bandle$DMSO, 'bandle_alloc', unknown='Undefined')

plot_tsne(combined_protein_res_inc_bandle$Thapsigargin, 'bandle_alloc', unknown='Undefined')

plot_tsne(combined_protein_res_inc_bandle$DMSO, 'markers', foi=potential_sg_markers)

plot_tsne(combined_protein_res_inc_bandle$Thapsigargin, 'markers', foi=potential_sg_markers)

plot_tsne(combined_protein_res_inc_bandle$DMSO, 'bandle_alloc', foi=potential_sg_markers, unknown='Undefined')

plot_tsne(combined_protein_res_inc_bandle$Thapsigargin, 'bandle_alloc', foi=potential_sg_markers, unknown='Undefined')

Calculate all vs all correlations and then identify potential new SG proteins as those top 1% most highly correlated with our 4 proteins, plus correlation > 0.35 greater than correlation with ribosomes.

all_cor <- combined_protein_res_inc_bandle[[2]] %>% exprs() %>% t() %>% cor(method='pearson')

wh <- which(rownames(all_cor) %in% potential_sg_markers)

mean_cor_with_potential_sg <- all_cor[,wh] %>% rowMeans()



mean_cor_with_potential_sg[wh]
   P11940    Q13310    Q92900    Q9NUL3 
0.9322607 0.9185716 0.8253327 0.8607352 
mean_cor_with_ribosome <- all_cor[,which(getMarkers(combined_protein_res_inc_bandle[[2]])=='RIBOSOME')] %>% rowMeans()
organelleMarkers
        CYTOSOL              ER           GOLGI        LYSOSOME    MITOCHONDRIA   NUCLEOPLASM-1   NUCLEOPLASM-2 
             68              83              35              27             150              27              19 
        NUCLEUS      PEROXISOME              PM PROTEIN COMPLEX        RIBOSOME         unknown 
             74              14              57              62              66            4632 
hist(mean_cor_with_potential_sg)

hist(mean_cor_with_potential_sg-mean_cor_with_ribosome)

summary(mean_cor_with_potential_sg-mean_cor_with_ribosome)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
-0.52672 -0.38363 -0.00206 -0.02010  0.25158  0.68978 
potential_new_sg <- names(mean_cor_with_potential_sg)[
  ((mean_cor_with_potential_sg-mean_cor_with_ribosome)>0.35 &
     mean_cor_with_potential_sg > quantile(mean_cor_with_potential_sg, 0.99))] %>% 
  setdiff(potential_sg_markers)

Looking at localisation of thse potential SG proteins.

plot_fois(potential_new_sg, foi_name='Potential SG',
          moi=c('CYTOSOL', 'RIBOSOME', 'ER', 'NUCLEUS', 'PROTEIN COMPLEX'),
          feature_col='bandle_alloc',
          plot_tsne=TRUE, unknown_desc='Undefined')

NA
NA

What are the 22 potential new SG proteins…


fData(combined_protein_res_inc_bandle$Thapsigargin)[potential_new_sg,174:182]

Profiles for all 22 proteins

compare_profiles(potential_new_sg) + facet_wrap(~name, ncol=6)

OK, let’s note down what we think about the above 22 proteins

Confident RNA granule proteins (PB and/or SG) = 10 proteins

CASC3 (https://www.uniprot.org/uniprot/O15234) - Recruited to SG (https://pubmed.ncbi.nlm.nih.gov/17652158/)

CNOT1,2,3,6L,9 - Part of CCR4-NOT complex which is known to be localised to RNP granules (e.g https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3376659/)

DCP1A, B (https://www.uniprot.org/uniprot/Q9NPI6; https://www.uniprot.org/uniprot/Q8IZD4) - Necessary for the degradation of mRNAs, both in normal mRNA turnover and in nonsense-mediated mRNA decay. Removes the 7-methyl guanine cap structure from mRNA molecules, yielding a 5’-phosphorylated mRNA fragment and 7m-GDP. Contributes to the transactivation of target genes after stimulation by TGFB1. PB localised

SECISBP2 (https://www.uniprot.org/uniprot/Q96T21) - Binds to the SECIS element in the 3’-UTR of some mRNAs encoding selenoproteins. Binding is stimulated by SELB. Found in SG (https://en.wikipedia.org/wiki/Stress_granule, inc Youn et al)

YBX3 https://www.uniprot.org/uniprot/P16989 YBX1 - Promotes mRNA stabilization: acts by binding to m5C-containing mRNAs and recruiting the mRNA stability maintainer ELAVL1, thereby preventing mRNA decay. Both YBX1 & 3 are often found in SG (https://en.wikipedia.org/wiki/Stress_granule, inc Youn et al for YBX3).

Plausible though undetected = 2 proteins

CAMK2D (https://www.uniprot.org/uniprot/Q13557) - Calcium/calmodulin-dependent protein kinase involved in the regulation of Ca2+ homeostatis!! Seems to be sarcoplasmic reticulum more than ER localised. CAMK2 has been implicated in RNP decondensation (https://elifesciences.org/articles/65742) so this is at least plausible granule localised

RANB9 (https://www.uniprot.org/uniprot/Q96S59) - Inhibits FMR1 binding to RNA (https://pubmed.ncbi.nlm.nih.gov/15381419/) and other RAN binding proteins are found in SG (https://en.wikipedia.org/wiki/Stress_granule) so plausible if not already known

CAMK2D & RANB9 are worth reading into more!

Implausible = 10 proteins

GIT1/2 (https://www.uniprot.org/uniprot/Q9Y2X7; https://www.uniprot.org/uniprot/Q14161) - Seems to localised in focal adhesions

HAUS3 (https://www.uniprot.org/uniprot/Q68CZ6) - Contributes to mitotic spindle assembly, maintenance of centrosome integrity and completion of cytokinesis as part of the HAUS augmin-like complex.

MKLN1 (https://www.uniprot.org/uniprot/Q9UL63) - Component of the CTLH E3 ubiquitin-protein ligase complex that selectively accepts ubiquitin from UBE2H and mediates ubiquitination and subsequent proteasomal degradation of the transcription factor HBP1

PRPS2 & PRPSAP1 (https://www.uniprot.org/uniprot/P11908; https://www.uniprot.org/uniprot/Q14558) - Catalyzes the synthesis of phosphoribosylpyrophosphate (PRPP) that is essential for nucleotide synthesis; Seems to play a negative regulatory role in 5-phosphoribose 1-diphosphate synthesis.

RMND5A (https://www.uniprot.org/uniprot/Q9H871) - Core component of the CTLH E3 ubiquitin-protein ligase

RNF213 (https://www.uniprot.org/uniprot/Q63HN8) - E3 ubiquitin-protein ligase involved in angiogenesis. Other RNFs (214, 219, 25) have been detected in SGs before (https://en.wikipedia.org/wiki/Stress_granule)

SEPTIN6/8 (https://www.uniprot.org/uniprot/Q14141; https://www.uniprot.org/uniprot/Q92599) - Filament-forming cytoskeletal GTPases. Required for normal organization of the actin cytoskeleton.

Explaining the above:

My interpretation: RMND5A may be worth following up but the others look likely to be FPs.

10/22 proteins being strongly P-body/SG does suggest we may be resolving macromolecular content of the granule in our density gradient!

LS0tCnRpdGxlOiAiUHJvdGVpbnMgaW4gZ3JhbnVsZXMiCmF1dGhvcjoKICAtIG5hbWU6ICJUb20gU21pdGgiCiAgICBhZmZpbGlhdGlvbjogIkNhbWJyaWRnZSBDZW50cmUgZm9yIFByb3Rlb21pY3MiCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKYWJzdHJhY3Q6IHwgCiAgSGVyZSwgd2UgZXhwbG9yZSB0aGUgcG90ZW50aWFsIGdyYW51bGUtbG9jYWxpc2VkIHByb3RlaW5zCm91dHB1dDoKICBwZGZfZG9jdW1lbnQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdApnZW9tZXRyeTogbWFyZ2luPTFpbgpmb250c2l6ZTogMTFwdAotLS0KCgpgYGB7cn0KbGlicmFyeShNU25iYXNlKQpsaWJyYXJ5KHBSb2xvYykKbGlicmFyeShwUm9sb2NFeHQpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGNhbXByb3RSKQpsaWJyYXJ5KGJpb2Jyb29tKQoKc291cmNlKCcuLi9wbG90X2ZvaS5SJykKCmNvbG91cnMgPC0gcmVhZFJEUygnLi4vLi4vLi4vLi4vNl9zaGlueV9hcHAvb3V0L3NoaW55X2NvbG91cnMucmRzJykkUHJvdGVpbgpgYGAKClJlYWQgaW4gQkFORExFIHJlc3VsdHMgYW5kIGZ1bGx5IGFubm90YXRlZCBMT1BJVCBkYXRhCmBgYHtyfQpkaWZmX2xvYyA8LSByZWFkUkRTKCcuLi8uLi9vdXQvYmFuZGxlX2RpZmZfbG9jX2FsbF91bmlxdWUucmRzJykKCmNvbWJpbmVkX3Byb3RlaW5fcmVzX2luY19iYW5kbGUgPC0gcmVhZFJEUygnLi4vLi4vb3V0L2NvbWJpbmVkX3Byb3RlaW5fcmVzX2luY19iYW5kbGVfbG9jLnJkcycpCgpgYGAKCkp1c3QgbG9va2luZyBhdCB0aGUgcHJvZmlsZSBmb3IgWk5GNjIyCmBgYHtyfQptYXJrZXJfcHJvZmlsZXMgPC0gY29tYmluZWRfcHJvdGVpbl9yZXNfaW5jX2JhbmRsZSAlPiUgbmFtZXMoKSAlPiUKICBsYXBwbHkoZnVuY3Rpb24obmFtZSl7CiAgICBtcmtDb25zUHJvZmlsZXMoY29tYmluZWRfcHJvdGVpbl9yZXNfaW5jX2JhbmRsZVtbbmFtZV1dKVtjKCdFUicsICdSSUJPU09NRScpLF0gJT4lCiAgICAgIGRhdGEuZnJhbWUoKSAlPiUKICAgICAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oJ21hcmtlcnMnKSAlPiUKICAgICAgcGl2b3RfbG9uZ2VyKGNvbHM9LW1hcmtlcnMsIG5hbWVzX3RvPSdzYW1wbGUnKSAlPiUKICAgICAgbXV0YXRlKHNhbXBsZT1yZW1vdmVfeChzYW1wbGUpKSAlPiUKICAgICAgbXV0YXRlKGNvbmRpdGlvbj1uYW1lKSAlPiUKICAgICAgbWVyZ2UocERhdGEoY29tYmluZWRfcHJvdGVpbl9yZXNfaW5jX2JhbmRsZVtbbmFtZV1dKVssYygnZnJhY3Rpb24nLCAncmVwbGljYXRlJyldLAogICAgICAgICAgICBieS54PSdzYW1wbGUnLCBieS55PSdyb3cubmFtZXMnKQogIH0pICU+JSBiaW5kX3Jvd3MoKSAlPiUKICBtdXRhdGUobWFya2Vycz11cGRhdGVfbG9jX25hbWVzKG1hcmtlcnMpKQoKZm9pX3Byb2ZpbGUgPC0gY29tYmluZWRfcHJvdGVpbl9yZXNfaW5jX2JhbmRsZSAlPiUKICBsYXBwbHkoZnVuY3Rpb24oeCkgdGlkeSh4WydROTY5UzMnLF0sIGFkZFBoZW5vPVRSVUUpKSAlPiUKICBiaW5kX3Jvd3MoKSAlPiUKICBtdXRhdGUobWFya2Vycz0nWk5GNjIyJykKCgpwIDwtIGJpbmRfcm93cyhmb2lfcHJvZmlsZSwgbWFya2VyX3Byb2ZpbGVzKSAlPiUKICBtdXRhdGUoY29uZGl0aW9uPXJlY29kZShjb25kaXRpb24sICdUaGFwc2lnYXJnaW4nPSdVUFInKSkgJT4lCiAgZ2dwbG90KGFlcyhmcmFjdGlvbiwgdmFsdWUsIGdyb3VwPWludGVyYWN0aW9uKHJlcGxpY2F0ZSwgbWFya2VycyksIGNvbG91cj1tYXJrZXJzKSkgKwogIGdlb21fbGluZShzaXplPTEpICsKICBmYWNldF9ncmlkKGNvbmRpdGlvbn4ocGFzdGUwKCdSZXBsaWNhdGUgJywgcmVwbGljYXRlKSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPTE6OCwgbmFtZT0nRnJhY3Rpb24nKSArCiAgdGhlbWVfY2FtcHJvdChiYXNlX3NpemU9MTUsIGJhc2VfZmFtaWx5PSdzYW5zJywgYm9yZGVyPUZBTFNFKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9Yyhjb2xvdXJzW2MoJ0VSJywgJ1JJQk9TT01FJyldLCBnZXRfY2F0X3BhbGV0dGUoNylbN10pLCBuYW1lPScnKSArCiAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZD1lbGVtZW50X2JsYW5rKCkpICsKICB4bGFiKCdGcmFjdGlvbicpICsKICB5bGFiKCdBYnVuZGFuY2UgKHN1bSBub3JtLiknKQoKcHJpbnQocCkKZ2dzYXZlKCcuLi8uLi8uLi8uLi81X21hbnVzY3JpcHRfZmlndXJlcy9GaWd1cmVfNS9tb2RlbC96bmY2MjIucG5nJywgd2lkdGg9NywgaGVpZ2h0PTMuNSkKZ2dzYXZlKCcuLi8uLi8uLi8uLi81X21hbnVzY3JpcHRfZmlndXJlcy9GaWd1cmVfNS9tb2RlbC96bmY2MjIucGRmJywgd2lkdGg9NywgaGVpZ2h0PTMuNSkKCgogICAgCgpgYGAKWk5GNjIyIGFuZCBDQU1LMkQKYGBge3J9CmZvaV9mb3JfdmFsaWRhdGlvbiA8LSBjKCdROTY5UzMnLCAnUTEzNTU3JykKY29tcGFyZV9wcm9maWxlcyhmb2lfZm9yX3ZhbGlkYXRpb24pCgpkaWZmX2xvYyAlPiUgZmlsdGVyKHByb3RlaW4gJWluJSBmb2lfZm9yX3ZhbGlkYXRpb24pCmBgYAoKTm93LCBvbnRvIHRoZSBwcm90ZWlucyBtb3ZpbmcgYXdheSBmcm9tIHRoZSByaWJvc29tZS4KYGBge3J9CmJhbmRsZV9mcm9tX3JpYm9zb21lIDwtIGRpZmZfbG9jICU+JQogIGZpbHRlcihiYW5kbGUuYWxsb2NhdGlvbi5kbXNvLm1pbmltYWw9PSdSSUJPU09NRScsIGxldmVsIT0nQ2FuZGlkYXRlJykKCnByaW50KGJhbmRsZV9mcm9tX3JpYm9zb21lKQoKY29tcGFyZV9wcm9maWxlcyhiYW5kbGVfZnJvbV9yaWJvc29tZSRwcm90ZWluKQoKcGxvdF9mb2lzKGFzLmNoYXJhY3RlcihiYW5kbGVfZnJvbV9yaWJvc29tZSRwcm90ZWluKSwgZm9pX25hbWU9J0F3YXkgZnJvbSByaWJvc29tZScsIGZlYXR1cmVfY29sPSdiYW5kbGVfYWxsb2MnLAogICAgICAgICAgbW9pPWMoJ0N5dG9zb2wnLCAnUmlib3NvbWUnLCAnRVInLCAnTnVjbGV1cycsICdQcm90ZWluIENvbXBsZXgnKSwgcGxvdF90c25lPVRSVUUsIHVua25vd25fZGVzYz0nVW5kZWZpbmVkJykKCgpgYGAKClBBQlBDMSwgUEFCUEM0LCBVUEYxICYgU1RBVTIgc2VlbSBxdWl0ZSBsaWtlbHkgdG8gYmUgbW92aW5nIHRvIGEgU3RyZXNzIEdyYW51bGUgKFNHKSBwcm9maWxlIGdpdmVuIGEpIFRoZXkgYXJlIGFzc29jaWF0ZWQgd2l0aCByaWJvc29tZXMgd2hlbiB0cmFuc2xhdGlvbiBpcyBhY3RpdmUsIGIpIG1vc3QgYXJlIGtub3duIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCBTRyB1cG9uIHN0cmVzcyAmIGMpIHRoZXkgaW5jcmVhc2UgaW4gYWJ1bmRhbmNlIGluIHRoZSBmcmFjdGlvbnMgaW5kaWNhdGl2ZSBvZiBncmFudWxlcyBpbiB0aGUgTG9STkEgZGF0YSAoZnJhY3Rpb24gNSAmIDYpLgoKV2hlcmVhcywgTUFHRUIyICYgUEEyRzQgc2VlbSB0byBtb3ZlIHRvd2FyZHMgY3l0b3NvbCBpZiBhbnl0aGluZy4KClBBMkc0IC0gcmVndWxhdGVzIGNhcC1pbmRlcGVuZGVudCBJUkVTLW1lZGlhdGVkIHRyYW5zbGF0aW9uCgpDYW4gd2UgaWRlbnRpZnkgZnVydGhlciBwcm90ZWlucyB3aGljaCBhcmUgc2ltaWxhcmx5IGxvY2FsaXNlZCBpbiBUZyBieSBqdXN0IHVzaW5nIGNvcnJlbGF0aW9uIHdpdGggdGhlIGFib3ZlLgoKYGBge3J9CnBvdGVudGlhbF9zZ19tYXJrZXJzIDwtIGJhbmRsZV9mcm9tX3JpYm9zb21lICU+JSBmaWx0ZXIoZ3JlcGwoJyhQQUJQfFVQRjF8U1RBVTIpJywgYEdFTkVTYCkpICU+JSBwdWxsKHByb3RlaW4pCgpwIDwtIGNvbXBhcmVfcHJvZmlsZXMocG90ZW50aWFsX3NnX21hcmtlcnMpCnByaW50KHApCgpnZ3NhdmUoJy4uLy4uLy4uLy4uLzVfbWFudXNjcmlwdF9maWd1cmVzL0ZpZ3VyZV80L2dyYW51bGVzL2JhbmRsZV9yZWxvYy5wbmcnLCB3aWR0aD01LCBoZWlnaHQ9NSkKZ2dzYXZlKCcuLi8uLi8uLi8uLi81X21hbnVzY3JpcHRfZmlndXJlcy9GaWd1cmVfNC9ncmFudWxlcy9iYW5kbGVfcmVsb2MucGRmJywgd2lkdGg9NSwgaGVpZ2h0PTUpCgpwbG90X2ZvaXMocG90ZW50aWFsX3NnX21hcmtlcnMsIGZvaV9uYW1lPSdQQUJQQzEvNCwgVVBGMSwgU1RBVTInLCBmZWF0dXJlX2NvbD0nYmFuZGxlX2FsbG9jJywKICAgICAgICAgIG1vaT1jKCdDeXRvc29sJywgJ051Y2xldXMnLCAnUmlib3NvbWUnKSwgcGxvdF90c25lPVRSVUUsIHVua25vd25fZGVzYz0nVW5kZWZpbmVkJywgKQoKYGBgCgoKCmBgYHtyfQpwbG90X3RzbmUoY29tYmluZWRfcHJvdGVpbl9yZXNfaW5jX2JhbmRsZSRETVNPLCAnbWFya2VycycpCnBsb3RfdHNuZShjb21iaW5lZF9wcm90ZWluX3Jlc19pbmNfYmFuZGxlJFRoYXBzaWdhcmdpbiwgJ21hcmtlcnMnKQpwbG90X3RzbmUoY29tYmluZWRfcHJvdGVpbl9yZXNfaW5jX2JhbmRsZSRETVNPLCAnYmFuZGxlX2FsbG9jJywgdW5rbm93bj0nVW5kZWZpbmVkJykKcGxvdF90c25lKGNvbWJpbmVkX3Byb3RlaW5fcmVzX2luY19iYW5kbGUkVGhhcHNpZ2FyZ2luLCAnYmFuZGxlX2FsbG9jJywgdW5rbm93bj0nVW5kZWZpbmVkJykKYGBgCgpgYGB7cn0KcGxvdF90c25lKGNvbWJpbmVkX3Byb3RlaW5fcmVzX2luY19iYW5kbGUkRE1TTywgJ21hcmtlcnMnLCBmb2k9cG90ZW50aWFsX3NnX21hcmtlcnMpCnBsb3RfdHNuZShjb21iaW5lZF9wcm90ZWluX3Jlc19pbmNfYmFuZGxlJFRoYXBzaWdhcmdpbiwgJ21hcmtlcnMnLCBmb2k9cG90ZW50aWFsX3NnX21hcmtlcnMpCnBsb3RfdHNuZShjb21iaW5lZF9wcm90ZWluX3Jlc19pbmNfYmFuZGxlJERNU08sICdiYW5kbGVfYWxsb2MnLCBmb2k9cG90ZW50aWFsX3NnX21hcmtlcnMsIHVua25vd249J1VuZGVmaW5lZCcpCnBsb3RfdHNuZShjb21iaW5lZF9wcm90ZWluX3Jlc19pbmNfYmFuZGxlJFRoYXBzaWdhcmdpbiwgJ2JhbmRsZV9hbGxvYycsIGZvaT1wb3RlbnRpYWxfc2dfbWFya2VycywgdW5rbm93bj0nVW5kZWZpbmVkJykKYGBgCkNhbGN1bGF0ZSBhbGwgdnMgYWxsIGNvcnJlbGF0aW9ucyBhbmQgdGhlbiBpZGVudGlmeSBwb3RlbnRpYWwgbmV3IFNHIHByb3RlaW5zIGFzIHRob3NlIHRvcCAxJSBtb3N0IGhpZ2hseSBjb3JyZWxhdGVkIHdpdGggb3VyIDQgcHJvdGVpbnMsIHBsdXMgY29ycmVsYXRpb24gPiAwLjM1IGdyZWF0ZXIgdGhhbiBjb3JyZWxhdGlvbiB3aXRoIHJpYm9zb21lcy4KYGBge3J9CmFsbF9jb3IgPC0gY29tYmluZWRfcHJvdGVpbl9yZXNfaW5jX2JhbmRsZVtbMl1dICU+JSBleHBycygpICU+JSB0KCkgJT4lIGNvcihtZXRob2Q9J3BlYXJzb24nKQoKd2ggPC0gd2hpY2gocm93bmFtZXMoYWxsX2NvcikgJWluJSBwb3RlbnRpYWxfc2dfbWFya2VycykKCm1lYW5fY29yX3dpdGhfcG90ZW50aWFsX3NnIDwtIGFsbF9jb3JbLHdoXSAlPiUgcm93TWVhbnMoKQoKCgptZWFuX2Nvcl93aXRoX3BvdGVudGlhbF9zZ1t3aF0KCm1lYW5fY29yX3dpdGhfcmlib3NvbWUgPC0gYWxsX2Nvclssd2hpY2goZ2V0TWFya2Vycyhjb21iaW5lZF9wcm90ZWluX3Jlc19pbmNfYmFuZGxlW1syXV0pPT0nUklCT1NPTUUnKV0gJT4lIHJvd01lYW5zKCkKCmhpc3QobWVhbl9jb3Jfd2l0aF9wb3RlbnRpYWxfc2cpCmhpc3QobWVhbl9jb3Jfd2l0aF9wb3RlbnRpYWxfc2ctbWVhbl9jb3Jfd2l0aF9yaWJvc29tZSkKc3VtbWFyeShtZWFuX2Nvcl93aXRoX3BvdGVudGlhbF9zZy1tZWFuX2Nvcl93aXRoX3JpYm9zb21lKQoKcG90ZW50aWFsX25ld19zZyA8LSBuYW1lcyhtZWFuX2Nvcl93aXRoX3BvdGVudGlhbF9zZylbCiAgKChtZWFuX2Nvcl93aXRoX3BvdGVudGlhbF9zZy1tZWFuX2Nvcl93aXRoX3JpYm9zb21lKT4wLjM1ICYKICAgICBtZWFuX2Nvcl93aXRoX3BvdGVudGlhbF9zZyA+IHF1YW50aWxlKG1lYW5fY29yX3dpdGhfcG90ZW50aWFsX3NnLCAwLjk5KSldICU+JSAKICBzZXRkaWZmKHBvdGVudGlhbF9zZ19tYXJrZXJzKQoKCmBgYApMb29raW5nIGF0IGxvY2FsaXNhdGlvbiBvZiB0aHNlIHBvdGVudGlhbCBTRyBwcm90ZWlucy4KYGBge3J9CnBsb3RfZm9pcyhwb3RlbnRpYWxfbmV3X3NnLCBmb2lfbmFtZT0nUG90ZW50aWFsIFNHJywKICAgICAgICAgIG1vaT1jKCdDWVRPU09MJywgJ1JJQk9TT01FJywgJ0VSJywgJ05VQ0xFVVMnLCAnUFJPVEVJTiBDT01QTEVYJyksCiAgICAgICAgICBmZWF0dXJlX2NvbD0nYmFuZGxlX2FsbG9jJywKICAgICAgICAgIHBsb3RfdHNuZT1UUlVFLCB1bmtub3duX2Rlc2M9J1VuZGVmaW5lZCcpCgpgYGAKV2hhdCBhcmUgdGhlIDIyIHBvdGVudGlhbCBuZXcgU0cgcHJvdGVpbnMuLi4KCmBgYHtyfQoKZkRhdGEoY29tYmluZWRfcHJvdGVpbl9yZXNfaW5jX2JhbmRsZSRUaGFwc2lnYXJnaW4pW3BvdGVudGlhbF9uZXdfc2csMTc0OjE4Ml0KYGBgCgoKCgpQcm9maWxlcyBmb3IgYWxsIDIyIHByb3RlaW5zCmBgYHtyLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04fQpjb21wYXJlX3Byb2ZpbGVzKHBvdGVudGlhbF9uZXdfc2cpICsgZmFjZXRfd3JhcCh+bmFtZSwgbmNvbD02KQpgYGAKCgpPSywgbGV0J3Mgbm90ZSBkb3duIHdoYXQgd2UgdGhpbmsgYWJvdXQgdGhlIGFib3ZlIDIyIHByb3RlaW5zCgoqQ29uZmlkZW50IFJOQSBncmFudWxlIHByb3RlaW5zIChQQiBhbmQvb3IgU0cpID0gMTAgcHJvdGVpbnMqCgpDQVNDMyAoaHR0cHM6Ly93d3cudW5pcHJvdC5vcmcvdW5pcHJvdC9PMTUyMzQpIC0gUmVjcnVpdGVkIHRvIFNHIChodHRwczovL3B1Ym1lZC5uY2JpLm5sbS5uaWguZ292LzE3NjUyMTU4LykKCkNOT1QxLDIsMyw2TCw5IC0gUGFydCBvZiBDQ1I0LU5PVCBjb21wbGV4IHdoaWNoIGlzIGtub3duIHRvIGJlIGxvY2FsaXNlZCB0byBSTlAgZ3JhbnVsZXMgKGUuZyBodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3BtYy9hcnRpY2xlcy9QTUMzMzc2NjU5LykKCkRDUDFBLCBCIChodHRwczovL3d3dy51bmlwcm90Lm9yZy91bmlwcm90L1E5TlBJNjsgaHR0cHM6Ly93d3cudW5pcHJvdC5vcmcvdW5pcHJvdC9ROElaRDQpIC0gTmVjZXNzYXJ5IGZvciB0aGUgZGVncmFkYXRpb24gb2YgbVJOQXMsIGJvdGggaW4gbm9ybWFsIG1STkEgdHVybm92ZXIgYW5kIGluIG5vbnNlbnNlLW1lZGlhdGVkIG1STkEgZGVjYXkuIFJlbW92ZXMgdGhlIDctbWV0aHlsIGd1YW5pbmUgY2FwIHN0cnVjdHVyZSBmcm9tIG1STkEgbW9sZWN1bGVzLCB5aWVsZGluZyBhIDUnLXBob3NwaG9yeWxhdGVkIG1STkEgZnJhZ21lbnQgYW5kIDdtLUdEUC4gQ29udHJpYnV0ZXMgdG8gdGhlIHRyYW5zYWN0aXZhdGlvbiBvZiB0YXJnZXQgZ2VuZXMgYWZ0ZXIgc3RpbXVsYXRpb24gYnkgVEdGQjEuIFBCIGxvY2FsaXNlZAoKU0VDSVNCUDIgKGh0dHBzOi8vd3d3LnVuaXByb3Qub3JnL3VuaXByb3QvUTk2VDIxKSAtIEJpbmRzIHRvIHRoZSBTRUNJUyBlbGVtZW50IGluIHRoZSAzJy1VVFIgb2Ygc29tZSBtUk5BcyBlbmNvZGluZyBzZWxlbm9wcm90ZWlucy4gQmluZGluZyBpcyBzdGltdWxhdGVkIGJ5IFNFTEIuIEZvdW5kIGluIFNHIChodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TdHJlc3NfZ3JhbnVsZSwgaW5jIFlvdW4gZXQgYWwpCgpZQlgzIGh0dHBzOi8vd3d3LnVuaXByb3Qub3JnL3VuaXByb3QvUDE2OTg5IFlCWDEgLSBQcm9tb3RlcyBtUk5BIHN0YWJpbGl6YXRpb246IGFjdHMgYnkgYmluZGluZyB0byBtNUMtY29udGFpbmluZyBtUk5BcyBhbmQgcmVjcnVpdGluZyB0aGUgbVJOQSBzdGFiaWxpdHkgbWFpbnRhaW5lciBFTEFWTDEsIHRoZXJlYnkgcHJldmVudGluZyBtUk5BIGRlY2F5LiBCb3RoIFlCWDEgJiAzIGFyZSBvZnRlbiBmb3VuZCBpbiBTRyAoaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3RyZXNzX2dyYW51bGUsIGluYyBZb3VuIGV0IGFsIGZvciBZQlgzKS4gCgoqUGxhdXNpYmxlIHRob3VnaCB1bmRldGVjdGVkID0gMiBwcm90ZWlucyoKCkNBTUsyRCAoaHR0cHM6Ly93d3cudW5pcHJvdC5vcmcvdW5pcHJvdC9RMTM1NTcpIC0gQ2FsY2l1bS9jYWxtb2R1bGluLWRlcGVuZGVudCBwcm90ZWluIGtpbmFzZSBpbnZvbHZlZCBpbiB0aGUgcmVndWxhdGlvbiBvZiBDYTIrIGhvbWVvc3RhdGlzISEgU2VlbXMgdG8gYmUgc2FyY29wbGFzbWljIHJldGljdWx1bSBtb3JlIHRoYW4gRVIgbG9jYWxpc2VkLiBDQU1LMiBoYXMgYmVlbiBpbXBsaWNhdGVkIGluIFJOUCBkZWNvbmRlbnNhdGlvbiAoaHR0cHM6Ly9lbGlmZXNjaWVuY2VzLm9yZy9hcnRpY2xlcy82NTc0Mikgc28gdGhpcyBpcyBhdCBsZWFzdCBwbGF1c2libGUgZ3JhbnVsZSBsb2NhbGlzZWQKClJBTkI5IChodHRwczovL3d3dy51bmlwcm90Lm9yZy91bmlwcm90L1E5NlM1OSkgLSBJbmhpYml0cyBGTVIxIGJpbmRpbmcgdG8gUk5BIChodHRwczovL3B1Ym1lZC5uY2JpLm5sbS5uaWguZ292LzE1MzgxNDE5LykgYW5kIG90aGVyIFJBTiBiaW5kaW5nIHByb3RlaW5zIGFyZSBmb3VuZCBpbiBTRyAoaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3RyZXNzX2dyYW51bGUpIHNvIHBsYXVzaWJsZSBpZiBub3QgYWxyZWFkeSBrbm93bgoKCkNBTUsyRCAmIFJBTkI5IGFyZSB3b3J0aCByZWFkaW5nIGludG8gbW9yZSEKCipJbXBsYXVzaWJsZSA9IDEwIHByb3RlaW5zKgoKR0lUMS8yIChodHRwczovL3d3dy51bmlwcm90Lm9yZy91bmlwcm90L1E5WTJYNzsgaHR0cHM6Ly93d3cudW5pcHJvdC5vcmcvdW5pcHJvdC9RMTQxNjEpIC0gU2VlbXMgdG8gbG9jYWxpc2VkIGluIGZvY2FsIGFkaGVzaW9ucwoKSEFVUzMgKGh0dHBzOi8vd3d3LnVuaXByb3Qub3JnL3VuaXByb3QvUTY4Q1o2KSAtIENvbnRyaWJ1dGVzIHRvIG1pdG90aWMgc3BpbmRsZSBhc3NlbWJseSwgbWFpbnRlbmFuY2Ugb2YgY2VudHJvc29tZSBpbnRlZ3JpdHkgYW5kIGNvbXBsZXRpb24gb2YgY3l0b2tpbmVzaXMgYXMgcGFydCBvZiB0aGUgSEFVUyBhdWdtaW4tbGlrZSBjb21wbGV4LgoKTUtMTjEgKGh0dHBzOi8vd3d3LnVuaXByb3Qub3JnL3VuaXByb3QvUTlVTDYzKSAtIENvbXBvbmVudCBvZiB0aGUgQ1RMSCBFMyB1YmlxdWl0aW4tcHJvdGVpbiBsaWdhc2UgY29tcGxleCB0aGF0IHNlbGVjdGl2ZWx5IGFjY2VwdHMgdWJpcXVpdGluIGZyb20gVUJFMkggYW5kIG1lZGlhdGVzIHViaXF1aXRpbmF0aW9uIGFuZCBzdWJzZXF1ZW50IHByb3RlYXNvbWFsIGRlZ3JhZGF0aW9uIG9mIHRoZSB0cmFuc2NyaXB0aW9uIGZhY3RvciBIQlAxCgoKUFJQUzIgJiBQUlBTQVAxIChodHRwczovL3d3dy51bmlwcm90Lm9yZy91bmlwcm90L1AxMTkwODsgaHR0cHM6Ly93d3cudW5pcHJvdC5vcmcvdW5pcHJvdC9RMTQ1NTgpIC0gQ2F0YWx5emVzIHRoZSBzeW50aGVzaXMgb2YgcGhvc3Bob3JpYm9zeWxweXJvcGhvc3BoYXRlIChQUlBQKSB0aGF0IGlzIGVzc2VudGlhbCBmb3IgbnVjbGVvdGlkZSBzeW50aGVzaXM7IFNlZW1zIHRvIHBsYXkgYSBuZWdhdGl2ZSByZWd1bGF0b3J5IHJvbGUgaW4gNS1waG9zcGhvcmlib3NlIDEtZGlwaG9zcGhhdGUgc3ludGhlc2lzLgoKUk1ORDVBIChodHRwczovL3d3dy51bmlwcm90Lm9yZy91bmlwcm90L1E5SDg3MSkgLSBDb3JlIGNvbXBvbmVudCBvZiB0aGUgQ1RMSCBFMyB1YmlxdWl0aW4tcHJvdGVpbiBsaWdhc2UgCgpSTkYyMTMgKGh0dHBzOi8vd3d3LnVuaXByb3Qub3JnL3VuaXByb3QvUTYzSE44KSAtIEUzIHViaXF1aXRpbi1wcm90ZWluIGxpZ2FzZSBpbnZvbHZlZCBpbiBhbmdpb2dlbmVzaXMuIE90aGVyIFJORnMgKDIxNCwgMjE5LCAyNSkgaGF2ZSBiZWVuIGRldGVjdGVkIGluIFNHcyBiZWZvcmUgKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N0cmVzc19ncmFudWxlKQoKClNFUFRJTjYvOCAoaHR0cHM6Ly93d3cudW5pcHJvdC5vcmcvdW5pcHJvdC9RMTQxNDE7IGh0dHBzOi8vd3d3LnVuaXByb3Qub3JnL3VuaXByb3QvUTkyNTk5KSAtIEZpbGFtZW50LWZvcm1pbmcgY3l0b3NrZWxldGFsIEdUUGFzZXMuIFJlcXVpcmVkIGZvciBub3JtYWwgb3JnYW5pemF0aW9uIG9mIHRoZSBhY3RpbiBjeXRvc2tlbGV0b24uIAoKCkV4cGxhaW5pbmcgdGhlIGFib3ZlOgoKLSBJIGNhbid0IGZpbmQgYW55IGNvbnZpbmNpbmcgbGluayBiZXR3ZWVuIEZBIGFuZCBQQi9TRwoKLSBMb3RzIG9mIHViaXF1aXRpbi1yZWxhdGVkIHByb3RlaW5zIGhhdmUgYmVlbiBvYnNlcnZlZCBpbiBTRyBiZWZvcmUsIGluY2x1ZGluZyB1YmlxdWl0aW4tcHJvdGVpbiBsaWdhc2VzcyAoaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3RyZXNzX2dyYW51bGU7IERUTCwgRFRYM0wsIFRSSU0yMSwgVFJJTTI1LCBUUklNNTYsIFRSSU03MSwgVUJCICYgVUJMNSkuIEhvd2V2ZXIsIHViaXF1aXRpbmF0aW9uIGlzIGRpc3BlbnNhYmxlIHRvIFNHIGZvcm1hdGlvbiBhbmQgZGlzc29sdXRpb246IGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvcG1jL2FydGljbGVzL1BNQzY1MDg2NjYvCgoKCk15IGludGVycHJldGF0aW9uOiAgUk1ORDVBIG1heSBiZSB3b3J0aCBmb2xsb3dpbmcgdXAgYnV0IHRoZSBvdGhlcnMgbG9vayBsaWtlbHkgdG8gYmUgRlBzLgoKCgoxMC8yMiBwcm90ZWlucyBiZWluZyBzdHJvbmdseSBQLWJvZHkvU0cgZG9lcyBzdWdnZXN0IHdlIG1heSBiZSByZXNvbHZpbmcgbWFjcm9tb2xlY3VsYXIgY29udGVudCBvZiB0aGUgZ3JhbnVsZSBpbiBvdXIgZGVuc2l0eSBncmFkaWVudCE=